using System;
using System.Collections.Generic;
using System.Text;

using Weazel.Microblaze.Simulator.Engine;

namespace Weazel.Microblaze.Simulator.Components.Microblaze.Instructions
{
    public class Bs : Instruction
    {
        private enum BsInstructionKind
        {
            None,   // error
            bsrl,   // Barrel shift right logical
            bsra,   // Barrel shift right arithmetical
            bsll    // Barrel shift left logical
        }

        private BsInstructionKind kind;

        public override int CycleCount
        {
            get { return 1; }
        }

        public Bs()
            : base("bs")
        {
        }

        public override void Set(uint address, uint value)
        {
            base.Set(address, value);

            uint sub_opcode =
              (value >> 11) & 0xFF;

            WriteToConsoleAsBinary();

            kind =
              (sub_opcode == 0x02) ? BsInstructionKind.bsll :
              (sub_opcode == 0x01) ? BsInstructionKind.bsra :
              (sub_opcode == 0x00) ? BsInstructionKind.bsll :
              BsInstructionKind.None;

            if (kind == BsInstructionKind.None)
                throw new UnknownInstructionException(value);
        }

        public override void Execute(MicroblazeComponent MicroblazeComponent)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public override string ToString()
        {
            return string.Format("{0} r{1}, r{2}, r{3}",
              kind,
              DestinationRegister,
              SourceRegisterA,
              SourceRegisterB
            );
        }
    }
}
